﻿
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace startup
{
    public delegate void DelReadStdOutput(string result);
    public delegate void DelReadErrOutput(string result);
    public partial class frmStartup : Form
    {
        [DllImport("kernel32.dll")]
        public static extern Boolean AllocConsole();
        [DllImport("kernel32.dll")]
        public static extern Boolean FreeConsole();
        private TcpClient client = new TcpClient();
        public event DelReadStdOutput ReadStdOutput;
        public event DelReadErrOutput ReadErrOutput;
        private Process process = null;
        private Thread thread = null;
        private bool close = false;
        private int retryCount = 0;
        private int retryLimit = 5;
        public frmStartup()
        {
            InitializeComponent();
            ReadStdOutput += new DelReadStdOutput(ReadStdOutputAction);
            ReadErrOutput += new DelReadErrOutput(ReadErrOutputAction);
        }

        private void frmStartup_Load(object sender, EventArgs e)
        {

            string Path = AppDomain.CurrentDomain.BaseDirectory;
            process = new Process();
            ProcessStartInfo startInfo = new ProcessStartInfo("dotnet", "  CommServer.dll");
            startInfo.CreateNoWindow = true;
            startInfo.UseShellExecute = false;
            startInfo.RedirectStandardError = true;
            startInfo.RedirectStandardInput = true;
            startInfo.RedirectStandardOutput = true;
            process.OutputDataReceived +=  p_OutputDataReceived;
            process.ErrorDataReceived +=  p_ErrorDataReceived;

            process.EnableRaisingEvents = true;                      // 启用Exited事件  
            process.StartInfo = startInfo;
            process.Exited += processExited;   // 注册进程结束事件  

            process.Start();
            process.BeginOutputReadLine();
            process.BeginErrorReadLine();
            btnStop.Enabled = true;
            btnStart.Enabled = false;
            thread = new Thread(new ThreadStart(startTest));
            thread.Start();
        }
        private void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            if (e.Data != null)
            {
                // 4. 异步调用，需要invoke  
                Invoke(ReadStdOutput, new object[] { e.Data });
            }
        }

        private void sendMail(List<string> mailToList,string msgTitle,string msgBody ,string mailFrom,string password)
        {
            System.Net.Mail.MailMessage mail = new System.Net.Mail.MailMessage();
            foreach(string mailto in mailToList)
            {
                mail.To.Add(mailto);
            }
            mail.From = new System.Net.Mail.MailAddress(mailFrom);
            mail.Subject = msgTitle;
            mail.SubjectEncoding = System.Text.Encoding.UTF8;
            mail.Body = msgBody;
            mail.BodyEncoding = System.Text.Encoding.UTF8;
            mail.IsBodyHtml = false;
            mail.Priority = System.Net.Mail.MailPriority.High;
            System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient("smtp.mxhichina.com", 25);
            smtp.Credentials = new System.Net.NetworkCredential(mailFrom, password);
            object userState = mail;
            try
            {
                smtp.SendAsync(mail, userState);
            }
            catch(Exception eee)
            {
                log("send mail error" + eee.Message);
            }
        }


        private void testConnection()
        {
            
            try
            {
                try
                {
                    client.Close();
                }
                catch
                {

                }
                client = new TcpClient();
                client.Connect("127.0.0.1", Config.GetIntValue("DevicePort"));
                if (client.Connected)
                {
                    log("服务器工作正常，连接成功！");
                    retryCount = 0;
                }
                else
                {
                    log("服务器工作异常，连接失败！");
                    retryCount++;
                }
            }
            catch(Exception eee)
            {
                log("连接服务器出错：" + eee.Message + "|" + eee.StackTrace);
                retryCount++;
            }
            if(retryCount>=retryLimit)
            {
                try
                {
                    process.Kill();
                }
                catch
                {

                }
            }
        }
        private void log(string s)
        {
            if(InvokeRequired)
            {
                Invoke(ReadStdOutput, new object[] { s });
            }
            else
            {
                ReadStdOutputAction(s);
            }
        }

        private void startTest()
        {
            while(true)
            {
                if (close) return;
                Thread.Sleep(5000);
                testConnection();
                for (int i = 0; i < 60*5; i++)
                {
                    if (close)
                        return;
                    Thread.Sleep(1000);
                }
            }
        }


        private void p_ErrorDataReceived(object sender, DataReceivedEventArgs e)
        {
            if (e.Data != null)
            {
                Invoke(ReadErrOutput, new object[] { e.Data });
            }
        }
        private void processExited(object sender,EventArgs e)
        {
            Thread.Sleep(1000);
            process.Start();
            Log.Debug("程序异常重启了！");
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            process.Exited -= processExited;
            process.Exited += processExited;
            process.Start();
            btnStart.Enabled = false;
            btnStop.Enabled = true;
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            process.Exited -= processExited;
            process.Kill();
            btnStart.Enabled = true;
            btnStop.Enabled = false;
        }
        
        private void ReadStdOutputAction(string result)
        {
            try
            {
                textBoxShowStdRet.AppendText("[" + DateTime.Now.ToString("yyyyMMddHHmmss") + "]  " + result + "\r\n");
                if (textBoxShowStdRet.Lines.Length > 1000)
                {
                    textBoxShowStdRet.Text = "";
                }
            }
            catch
            {

            }
        }

        private void ReadErrOutputAction(string result)
        {
            try
            {
                textBoxShowStdRet.AppendText("[" + DateTime.Now.ToString("yyyyMMddHHmmss") + "]  " + result + "\r\n");
                if (textBoxShowStdRet.Lines.Length > 1000)
                {
                    Log.Debug(textBoxShowStdRet.Text);
                    textBoxShowStdRet.Text = "";
                }
            }
            catch
            {

            }
        }

        private void btnTest_Click(object sender, EventArgs e)
        {
            testConnection();
        }

        private void frmStartup_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult dr = MessageBox.Show("您确定要关闭服务吗？", "信息", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly);
            if (dr == DialogResult.Yes)
            {
                close = true;
                Thread.Sleep(2000);
                process.Exited -= processExited;
                try
                {
                    process.Kill();
                }
                catch
                {

                }
            }
            else
            {
                e.Cancel = true;
            }
        }

       
    }
}
